#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "ftpclient.h"
#include <QDir>
#include <QFileDialog>
#include <QFuture>
#include <QFutureWatcher>
#include <QMessageBox>
MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow), m_ftpClient(new FtpClient())
{
    ui->setupUi(this);

    // 上传信号的回调
    connect(m_ftpClient, &FtpClient::uploadProgress, this, &MainWindow::onUploadProgress);
    connect(m_ftpClient, &FtpClient::uploadFinished, this, &MainWindow::onUploadFinished);
    connect(m_ftpClient, &FtpClient::uploadError, this, &MainWindow::onUploadError);

    ui->localDirEdit->setText(QApplication::applicationDirPath());
    on_getLocalDirBtn_clicked();
    on_getRemoteDirBtn_clicked();
    currentRemoteDir = "/";
    // 连接远程目录列表信号
    connect(m_ftpClient, &FtpClient::directoryListingReady,
        this, &MainWindow::onDirectoryListingReady);
    connect(m_ftpClient, &FtpClient::directoryListingError,
        this, &MainWindow::onDirectoryListingError);


    connect(&m_downloadWatcher, &QFutureWatcher<bool>::finished,
        this, &MainWindow::onDownloadFinshed);
    connect(m_ftpClient, &FtpClient::downloadProgress,
        this, &MainWindow::onDownloadProgress);

    ui->remoteListWidgetDir->setSelectionMode(QAbstractItemView::MultiSelection);
}

MainWindow::~MainWindow()
{
    delete ui;
}

//获取本地目录
void MainWindow::on_getLocalDirBtn_clicked()
{
    QString currentLocalPath = ui->localDirEdit->text();
    // 检查路径是否存在
    QDir dir(currentLocalPath);
    if (!dir.exists()) {
        ui->statusbar->showMessage("路径不存在: " + currentLocalPath);
        return;
    }

    // 清空列表
    ui->localListWidgetDir->clear();
    QFileInfoList fileList = dir.entryInfoList(
        QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot,
        QDir::DirsFirst | QDir::Name
    );
    if (dir.cdUp())
    {
        QListWidgetItem* parentDirItem = new QListWidgetItem("..");
        parentDirItem->setIcon(style()->standardIcon(QStyle::SP_DirIcon));
        parentDirItem->setData(Qt::UserRole, dir.absolutePath());
        ui->localListWidgetDir->addItem(parentDirItem);
        // 返回当前目录
        dir.cd(currentLocalPath);
    }
    for (const QFileInfo& fileInfo : fileList) {
        QListWidgetItem* item = new QListWidgetItem(fileInfo.fileName());
        if (fileInfo.isDir()) {
            item->setIcon(style()->standardIcon(QStyle::SP_DirIcon));
        }
        else {
            item->setIcon(style()->standardIcon(QStyle::SP_FileIcon));
        }
        // 存储完整路径作为用户数据
        item->setData(Qt::UserRole, fileInfo.absoluteFilePath());
        // 添加到列表
        ui->localListWidgetDir->addItem(item);
    }
    ui->statusbar->showMessage("已加载本地文件列表: " + currentLocalPath);
}
void MainWindow::on_localListWidgetDir_itemDoubleClicked(QListWidgetItem* item)
{
    QString filePath = item->data(Qt::UserRole).toString();
    QFileInfo fileInfo(filePath);

    if (fileInfo.isDir()) {
        // 如果是目录，切换到该目录
        //currentLocalPath = filePath;
        ui->localDirEdit->setText(filePath);
        on_getLocalDirBtn_clicked();
    }
    else {
        // 如果是文件，可以实现打开或其他操作
        ui->statusbar->showMessage("选中文件: " + filePath);
        // 这里可以添加文件上传逻辑
    }
}

// 上传逻辑
void MainWindow::on_uploadBtn_clicked()
{
    QList<QListWidgetItem*> selectedItems = ui->localListWidgetDir->selectedItems();
    if (selectedItems.isEmpty()) {
        QMessageBox::warning(this, "提示", "请选择要上传的文件");
        return;
    }
    if (selectedItems.size() > 1) {
        QMessageBox::warning(this, "提示", "请选择单个文件上传");
        return;
    }

    QListWidgetItem* item = selectedItems.first();
    QString localFilePath = item->data(Qt::UserRole).toString(); // 获取完整路径
    QFileInfo fileInfo(localFilePath);

    // 检查是否为文件
    if (!fileInfo.isFile()) {
        QMessageBox::warning(this, "提示", "请选择文件进行上传，而不是目录");
        return;
    }

    QString ftpUrl = ui->UrlEdit->text();
    QString username = ui->UserEdit->text();
    QString password = ui->passEdit->text();
    QString remoteDir = ui->remoteDirEdit->text();
    QString fileName = fileInfo.fileName(); // 从QFileInfo获取文件名

    if (remoteDir.isEmpty()) remoteDir = "/";
    QString remoteFile = remoteDir;
    if (!remoteFile.endsWith('/')) remoteFile += '/';
    remoteFile += fileName;

    ui->statusLabel->setText("准备上传: " + fileName);
    ui->uploadBtn->setEnabled(false);
    ui->progressBar->setValue(0);

    QFuture<bool> future = m_ftpClient->uploadFileAsync(
        ftpUrl, username, password, localFilePath, remoteFile
    );

    manageUploadTask(future, fileName);
}

void MainWindow::manageUploadTask(QFuture<bool> future, const QString& fileName)
{
    QFutureWatcher<bool>* watcher = new QFutureWatcher<bool>(this);
    watcher->setFuture(future);
    connect(watcher, &QFutureWatcher<bool>::finished, [this, watcher, fileName]() {
        bool success = watcher->result();
        ui->uploadBtn->setEnabled(true);

        if (success) {
            QMessageBox::information(this, "成功", "文件上传完成！");
            ui->statusLabel->setText("上传完成: " + fileName);
        }
        else {
            QMessageBox::critical(this, "失败", "文件上传失败");
            ui->statusLabel->setText("上传失败: " + fileName);
        }

        watcher->deleteLater();
        });

}



void MainWindow::onUploadProgress(const QString& fileName, int progress)
{
    ui->progressBar->setValue(progress);
    ui->statusLabel->setText(QString("上传进度: %1 - %2%").arg(fileName).arg(progress));
}

void MainWindow::onUploadFinished(const QString& fileName, bool success)
{
    if (success) {
        ui->statusLabel->setText("文件上传完成: " + fileName);
    }
    else {
        ui->statusLabel->setText("文件上传失败: " + fileName);
    }
}

void MainWindow::onUploadError(const QString& fileName, const QString& errorMessage)
{
    ui->statusLabel->setText("上传错误: " + fileName + " - " + errorMessage);
    QMessageBox::warning(this, "上传错误", errorMessage);
}

void MainWindow::on_getRemoteDirBtn_clicked()
{
    QString ftpUrl = ui->UrlEdit->text().trimmed();
    QString username = ui->UserEdit->text();
    QString password = ui->passEdit->text();
    QString directory = ui->remoteDirEdit->text().trimmed(); // 输入框中输入"uploads"

    if (directory.isEmpty()) {
        QMessageBox::warning(this, "提示", "请输入要打开的目录名称");
        return;
    }

    // 确保字符串前有斜杠
    if (!directory.startsWith('/')) {
        directory.prepend('/');
    }

    // 确保字符串后有斜杠
    if (!directory.endsWith('/')) {
        directory.append('/');
    }
    // 保存当前目录以便返回
    currentRemoteDir = directory;
    // 清空列表并显示加载状态
    ui->remoteListWidgetDir->clear();
    ui->statusLabel->setText("正在打开目录: " + directory);
    ui->getRemoteDirBtn->setEnabled(false);
    // 启动异步获取目录列表
    QFuture<QList<Ftp::FileInfo>> future = m_ftpClient->getDirectoryListingAsync(
        ftpUrl, username, password, directory);
    // 连接结果处理
    connect(&m_directoryWatcher, &QFutureWatcher<QList<Ftp::FileInfo>>::finished, [this, future, directory]() {
        if (future.isFinished()) {
            // 结果通过信号处理
        }
        });

    m_directoryWatcher.setFuture(future);
}


void MainWindow::onDirectoryListingReady(const QList<Ftp::FileInfo>& fileList)
{
    ui->remoteListWidgetDir->clear();

    QIcon folderIcon("");
    QIcon fileIcon("");
    if (folderIcon.isNull())
    {
        folderIcon = style()->standardIcon(QStyle::SP_DirIcon);
    }
    if (fileIcon.isNull())
    {
        fileIcon = style()->standardIcon(QStyle::SP_FileIcon);
    }
    QString currentPath = ui->remoteDirEdit->text().trimmed();
    if (currentPath != "/" && !currentPath.isEmpty()) {
        QListWidgetItem* parentDirItem = new QListWidgetItem(folderIcon, "..", ui->remoteListWidgetDir);
        parentDirItem->setData(Qt::UserRole, static_cast<int>(Ftp::FileType::TypeDirectory));
        ui->remoteListWidgetDir->addItem(parentDirItem);
    }

    for (const auto& file : fileList)
    {
        if (file.type == Ftp::FileType::TypeDirectory && file.name != "..") {
            QListWidgetItem* item = new QListWidgetItem(
                folderIcon,
                file.name,
                ui->remoteListWidgetDir);
            item->setData(Qt::UserRole, static_cast<int>(file.type)); // 存储类型信息
            ui->remoteListWidgetDir->addItem(item);
        }
        
    }
    // 添加文件项（跟在目录后面）
    for (const auto& file : fileList) {
        if (file.type == Ftp::FileType::TypeFile) {
            QListWidgetItem* item = new QListWidgetItem(
                fileIcon,
                file.name,
                ui->remoteListWidgetDir
            );
            item->setData(Qt::UserRole, static_cast<int>(file.type)); // 存储类型信息
            ui->remoteListWidgetDir->addItem(item);
        }
    }
    // 启用获取目录按钮
    ui->getRemoteDirBtn->setEnabled(true);
    // 打印调试信息
    qDebug() << "已更新远程目录列表，共" << ui->remoteListWidgetDir->count() << "项";
}
void MainWindow::on_remoteListWidgetDir_itemDoubleClicked(QListWidgetItem* item)
{
    Ftp::FileType type = static_cast<Ftp::FileType>(item->data(Qt::UserRole).toInt());
    if (type == Ftp::FileType::TypeDirectory)
    {
        QString currentPath = ui->remoteDirEdit->text().trimmed();
        // 确保路径格式正确
        if (!currentPath.endsWith('/')) {
            currentPath += '/';
        }
        QString itemName = item->text();
        if (itemName == "..")
        {
            // 处理返回上级目录
            QStringList pathParts = currentPath.split('/', Qt::SkipEmptyParts);
            if (!pathParts.isEmpty())
            {
                pathParts.removeLast();  // 移出最后一级目录
            }
            // 构建上级目录路径
            QString parentPath = "/"; // 根目录
            if (!pathParts.isEmpty()) {
                parentPath = "/" + pathParts.join("/") + "/";
            }
            // 更新路径显示
            ui->remoteDirEdit->setText(parentPath);
        }
        else {
            // 处理"进入子目录"
            QString newPath = currentPath + itemName + '/';
            ui->remoteDirEdit->setText(newPath);
        }
        // 重新加载目录
        on_getRemoteDirBtn_clicked();
    }
}
void MainWindow::onDirectoryListingError(const QString& errorMessage)
{
    ui->remoteListWidgetDir->clear();
    ui->remoteListWidgetDir->addItem("获取远程目录列表失败: " + errorMessage);
    ui->statusLabel->setText("获取远程目录列表失败");
    ui->getRemoteDirBtn->setEnabled(true);
    qDebug() << "远程目录列表错误:" << errorMessage;
}

void MainWindow::onDownloadFinshed()
{
    bool success = m_downloadWatcher.result();
    // ui->downloadButton->setEnabled(true);

    if (success) {
        ui->statusbar->showMessage("下载文件到exe所在目录的remoteFileLog文件夹下");
        QMessageBox::information(this, "成功", "文件下载完成！");
        ui->statusLabel->setText("下载完成");
    }
    else {
        QMessageBox::critical(this, "失败", "文件下载失败，请检查日志！");
        ui->statusLabel->setText("下载失败");
    }
}

void MainWindow::onDownloadProgress(const QString& fileName, int progress)
{
    ui->progressBar->setValue(progress);
    ui->statusLabel->setText(QString("%1 - 下载进度：%2%").arg(fileName).arg(progress));
}


void MainWindow::on_batchDownBtn_clicked()
{
    QList<QListWidgetItem*> selectedItems = ui->remoteListWidgetDir->selectedItems();
    if (selectedItems.isEmpty()) {
        QMessageBox::warning(this, "提示", "请先选择要下载的文件");
        return;
    }

    QString ftpUrl = ui->UrlEdit->text();
    QString username = ui->UserEdit->text();
    QString password = ui->passEdit->text();
    QString remoteDir = ui->remoteDirEdit->text();
    if (remoteDir.isEmpty()) remoteDir = "/";

    // 创建存储文件夹
    QString appDirPath = QApplication::applicationDirPath();
    QString storageFolder = appDirPath + "/remoteFileLog";
    QDir().mkpath(storageFolder);

    QList<QFuture<bool>> downloadFutures;
    for (QListWidgetItem* item : selectedItems) {
        QString remoteFile = item->text();
        // 清理文件名
        remoteFile = remoteFile.trimmed();
        remoteFile = remoteFile.replace("\r", "");
        remoteFile = remoteFile.replace("\n", "");
        remoteFile = remoteFile.replace("/", "_");
        remoteFile = remoteFile.replace("\\", "_");
        if (remoteFile.endsWith('/') || remoteFile.endsWith('\\')) continue;  // 跳过目录

        QString fullRemotePath = remoteDir + "/" + remoteFile;
        QString localFileName = remoteFile;
        QString localPath = storageFolder + "/" + localFileName;

        QFuture<bool> future = m_ftpClient->downloadFileAsync(
            ftpUrl, username, password, fullRemotePath, localPath
        );
        downloadFutures.append(future);
    }

    if (!downloadFutures.isEmpty()) {
        manageBatchDownload(downloadFutures);
    }
}

void MainWindow::manageBatchDownload(const QList<QFuture<bool>>& futures)
{
    ui->progressBar->setValue(0);
    ui->statusLabel->setText("开始批量下载...");
    ui->batchDownBtn->setEnabled(false);

    int totalTasks = futures.size();
    QAtomicInt* completedTasks = new QAtomicInt(1);

    for (const QFuture<bool>& future : futures) {
        QFutureWatcher<bool>* watcher = new QFutureWatcher<bool>(this);
        watcher->setFuture(future);

        connect(watcher, &QFutureWatcher<bool>::finished, [this, watcher, totalTasks, completedTasks]() {
            int completed = completedTasks->fetchAndAddRelaxed(1);
            int progress = (completed * 100) / totalTasks;
            ui->progressBar->setValue(progress);
            ui->statusLabel->setText(QString("批量下载：%1/%2 (%3%)").arg(completed).arg(totalTasks).arg(progress));

            if (completed == totalTasks) {
                ui->statusLabel->setText("批量下载完成");
                ui->batchDownBtn->setEnabled(true);
                ui->statusbar->showMessage("已下载文件到exe所在目录的remoteFileLog文件夹下");
                QMessageBox::information(this, "成功", "所有文件下载完成！");
            }
            });

        connect(watcher, &QFutureWatcher<bool>::finished, watcher, &QObject::deleteLater);
    }
}
